package com.noahplat.fourg.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.noahplat.alarm.feign.AlarmFeign;
import com.noahplat.alarm.pojo.Alarm;
import com.noahplat.common.cusexception.RedisException;
import com.noahplat.common.utils.NoahEnum;
import com.noahplat.common.utils.RedisUtils;
import com.noahplat.common.utils.Result;
import com.noahplat.datapro.pojo.*;
import com.noahplat.fence.pojo.Fence;
import com.noahplat.fourg.mapper.*;
import com.noahplat.fourg.service.FourgService;
import com.noahplat.oufu.feign.OtherGetMapFeign;
import com.noahplat.oufu.feign.OtherMapFeign;
import com.noahplat.user.feign.SconfigFeign;
import com.noahplat.user.pojo.Sconfig;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
public class FourgServiceImpl implements FourgService {

    public static final String TOKEN = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzY29wZSI6WyJhcHAiXSwibmFtZSI6IueZveWIqeWHryIsImFjY3RpZCI6MSwic3RpZCI6IjIiLCJwaWQiOm51bGwsImlkIjozNywidXNlclR5cGUiOiIyIiwiZXhwIjoxNzA1NDYzOTcwLCJhdXRob3JpdGllcyI6WyJub2FocGxhdC1zZXJ2aWNlLWFsYXJtOkFsYXJtQ29udHJvbGxlcjphZGRBbGFybSJdLCJqdGkiOiJmZWVjMGI4Ny0wMDQzLTQzNTUtODdlMi0wM2YwOTcxMGMxNTAiLCJjbGllbnRfaWQiOiJub2FocGxhdCIsInVzZXJuYW1lIjoiMTc4NjM5NzU2MzUifQ.AY0x-yMttkcdEGRCTJOmRWCVYecgHv0XovESb7ul4knklqhHsjtCgRjWGAIEPYRrLqyCpnpeo0JN6O0H1pKF7SHrKVqOc2O9Rosl00NgicbBZn_lhMmivtfTrCiZjxeHUxra1QshmfuoEydOu0NXprpDp0aq5l3tP60bNIALIsaeil3gDFPUrqU4UtmKxbOPs795_WaCehGZquMI3VkfjyUw_z16AWd5WJRGyW90ByKCwfzi3RcYCtNGQ-Z5EbCcfeGY0PVaeZC1AEB6LzhmCevFGftDClvDNMI1H2gaoY0rCnyRQcZtzH7Gog0N6pwVhP5JK70mI53kwGqj1CfzoA";
    public static final String GETMAKTOKEN="eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzY29wZSI6WyJhcHAiXSwibmFtZSI6IueZveWIqeWHryIsImFjY3RpZCI6MSwic3RpZCI6IjIiLCJwaWQiOm51bGwsImlkIjozNywidXNlclR5cGUiOiIyIiwiZXhwIjoxNzA1NDYzNzk5LCJhdXRob3JpdGllcyI6WyJub2FocGxhdC1zZXJ2aWNlLXVzZXI6U2NvbmZpZ0NvbnRyb2xsZXI6Z2V0TWFwbnVtIl0sImp0aSI6Ijg5ODZmYTQ4LTlkZjMtNGUzOC1iZmQ1LTg0ZDM5NThkNGYyMyIsImNsaWVudF9pZCI6Im5vYWhwbGF0IiwidXNlcm5hbWUiOiIxNzg2Mzk3NTYzNSJ9.H5RDysqummk98icFhKizj2WMUqCQgJCbOXjFBNEumDVAZE_-E1IF6Zu7XXclVgsl0bbmfxXHhJe_X0jGYx-AU4YLRuAePc2P484bpAr4rA1J81ynNFtGJRbF6fWkVLzfYUr3aUzDfHNTRihLhADK5aAzqZaq2Axe8wsjhWfz81782_S29j_m9Z84GA24evd48IqGSw8Ku4FivxeXhE5XC9WgJjUZvQpNhO_56a7ejEODZlOr9QoYEIHJKfiybITQNfvvL_31hu41YXjNxH6EavJhmJ-1_dmzjbxhqu-46ISGGdHqSobgxhXfRt2sJfPrcKCoE1CFBYu9HCw7OYWqNg";
    public static final String UPDATEMAKTOKEN="eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzY29wZSI6WyJhcHAiXSwibmFtZSI6IueZveWIqeWHryIsImFjY3RpZCI6MSwic3RpZCI6IjIiLCJwaWQiOm51bGwsImlkIjozNywidXNlclR5cGUiOiIyIiwiZXhwIjoxNzA1NDYzOTA0LCJhdXRob3JpdGllcyI6WyJub2FocGxhdC1zZXJ2aWNlLXVzZXI6U2NvbmZpZ0NvbnRyb2xsZXI6dXBkYXRlTWFwbnVtIl0sImp0aSI6ImIzM2UwMDhmLTVlMWYtNGUyNi05YzdiLTQ0MTkwNDRiYzVkYSIsImNsaWVudF9pZCI6Im5vYWhwbGF0IiwidXNlcm5hbWUiOiIxNzg2Mzk3NTYzNSJ9.HXJzpRzKmWN2GKB2z72WkOuRV-dZwFL1zaBGMBVRUnUHwRPRvcY6YhZjQHsDNMhVuwy3lutzgXkCxRwYxzlxbfeIysytPXXZJf87DVvvAo-EuxiJZ5iGNI110VfSSzHlUZxIW9v6CRprnJxLCtOwK60Jhn8GQoYFRGhjwurMNSXLBNhiSKonghHH4P8b4n5JWt3GPi_UQQ9qObF7pt-90aQ5R-v2KRNtQuP75Y4sSfn-cQN6rGT8oOn56lfRYV9UzDcW9XpgksHIJ5DoryxTzfp1hCI0R2dlzjvgGYzQTZqHMZyWEKgc0tdGAJIf9xmrGniTMcbmy7cNCQ4UMU9CcA";

    @Autowired
    private StepMapper stepMapper;
    @Autowired
    private SpMapper spMapper;
    @Autowired
    private BloodMapper bloodMapper;
    @Autowired
    private HeartMapper heartMapper;
    @Autowired
    private SiteMapper siteMapper;
    @Autowired
    private TempMapper tempMapper;

    @Autowired
    private OtherMapFeign otherMapFeign;
    @Autowired
    private OtherGetMapFeign otherGetMapFeign;
    @Autowired
    private AlarmFeign alarmFeign;
    @Autowired
    private SconfigFeign sconfigFeign;

    @Autowired
    private RedisUtils redisUtils;


        /**
         * 根据协议类型做设备推送数据做不同处理
         *
         * @param message
         * @return
         */
        public void getDeviceData(String message, ChannelHandlerContext ctx, String imei) {
            //获取当前时间
            Date date = new Date();
            //获取数据包类型
            String type = (message.split(",")[0]).split("\\*")[3];
            //获取数据包头
            String head = message.split("\\*")[0];
            //数据解析部分
            if ("KA".equals(type)) {//链路保持
                try {
                    String[] tem = message.split(",");
                    //获取步数
                    Integer step = Integer.valueOf(tem[2]);
                    //获取电量
                    Integer sp = Integer.valueOf(tem[4]);
                    //更新设备表
                    Step step1 = new Step();
                    step1.setTs(date);
                    step1.setImei(imei);
                    step1.setStep(step.toString());
                    step1.setModel("9820E");
                    step1.setProd("YUNXIN");
                    int i = stepMapper.insert(step1);

                    Sp sp1 = spMapper.selectImei(imei);
                    Sp newSp = new Sp();
                    if(ObjectUtils.isEmpty(sp1)){
                        newSp.setTs(date);
                    }else{
                        newSp.setTs(sp1.getTs());
                    }
                    newSp.setImei(imei);
                    newSp.setModel("9820E");
                    newSp.setProd("YUNXIN");
                    newSp.setSp(sp.toString());
                    newSp.setType("1");
                    int i1 = spMapper.insertImei(newSp);

                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    //应答终端
                    String msg = "[" + head + "*" + imei + "*0002*KA]";
                    ByteBuf respMsg = Unpooled.copiedBuffer(msg.getBytes());
                    ctx.writeAndFlush(respMsg);
                    ctx.flush();
                }
            } else if ("UD_LTE".equals(type) || "UD".equals(type) || "UD_CDMA".equals(type)) {//解析位置数据（仅限于移动联通卡，电信用户需另外实现）

                try {
                    //切割数据包
                    String[] tem = message.split(",");
                    //判断是否获取到定位数据，如果已经获取到定位数据，则需要调用高德api做坐标转换和逆地理编码解析；否则需要调用智能硬件定位接口定位
                    String flag = tem[3];
                    if("A".equals(flag)){

                        //动态去mapkey值
                        boolean keyres = redisUtils.hasKey(NoahEnum.GPSKEYDIR.getCode()+NoahEnum.GPSKEY.getCode());
                        if(!keyres){
                            Result result = sconfigFeign.getMapnum("1","Bearer "+GETMAKTOKEN);
                            if(!result.isFlag()){
                                return;
                            }
                            Map map = (Map) result.getData();
                            Sconfig sconfig1 = new Sconfig();
                            sconfig1.setId(Long.parseLong(map.get("id").toString()));
                            sconfig1.setMapkey(map.get("mapkey").toString());
                            sconfig1.setState( map.get("state").toString());
                            sconfig1.setType(map.get("type").toString());
                            boolean res = redisUtils.set(NoahEnum.GPSKEYDIR.getCode()+NoahEnum.GPSKEY.getCode(),sconfig1);
                            if(!res){
                                throw new RedisException();
                            }
                        }
                        Object object = redisUtils.getValue(NoahEnum.GPSKEYDIR.getCode()+NoahEnum.GPSKEY.getCode());
                        Sconfig sconfig = (Sconfig) object;
                        Long number  = redisUtils.incr(NoahEnum.GPSKEYDIR.getCode()+NoahEnum.GPSNUMKEY.getCode(),1);
                        String mapkey = sconfig.getMapkey();
                        if(number > 2900000){
                            redisUtils.lock(NoahEnum.GPSLOCK.getCode(),10);
                            Result result1 = sconfigFeign.updateMapnum(sconfig.getId(),"Bearer "+UPDATEMAKTOKEN);
                            if(!result1.isFlag()){
                                redisUtils.unlook(NoahEnum.GPSLOCK.getCode());
                                return;
                            }
                            Result result = sconfigFeign.getMapnum("0","Bearer "+GETMAKTOKEN);
                            if(!result.isFlag()){
                                redisUtils.unlook(NoahEnum.GPSLOCK.getCode());
                                return;
                            }
                            Map map = (Map) result.getData();
                            Sconfig sconfig1 = new Sconfig();
                            sconfig1.setId(Long.parseLong(map.get("id").toString()));
                            sconfig1.setMapkey(map.get("mapkey").toString());
                            sconfig1.setState( map.get("state").toString());
                            sconfig1.setType(map.get("type").toString());
                            boolean res = redisUtils.set(NoahEnum.GPSKEYDIR.getCode()+NoahEnum.GPSKEY.getCode(),sconfig1);
                            redisUtils.del(NoahEnum.GPSKEYDIR.getCode()+NoahEnum.GPSNUMKEY.getCode());
                            redisUtils.unlook(NoahEnum.GPSLOCK.getCode());
                            mapkey = map.get("mapkey").toString();
                        }
                        //获取经纬度
                        String longitude = tem[6];
                        String latitude = tem[4];
                        String s = longitude+","+latitude;

                        //GPS坐标转高德系坐标
                        String gps = otherMapFeign.getGDLocation(mapkey, s, "gps");
                        String locations = JSONObject.parseObject(gps).getString("locations");
                        //获取详情
                        String base = otherMapFeign.getLocationInfo("30ef23768c085fa4727bb286bb50cac5", locations, "base");
                        JSONObject regeocode = JSONObject.parseObject(base).getJSONObject("regeocode");
                        String devdesc = regeocode.getString("formatted_address");//位置详情
                        JSONObject addressComponent = regeocode.getJSONObject("addressComponent");
                        String city = addressComponent.getString("city");//城市
                        String province = addressComponent.getString("province");//省
                        String adcode = addressComponent.getString("adcode");//区域代码
                        String street = addressComponent.getJSONObject("streetNumber").getString("street");//街道
                        String country = addressComponent.getString("country");//国家
                        String citycode = addressComponent.getString("citycode");//城市代码
                        if(StringUtils.isEmpty(locations)){
                            return;
                        }

                        Site site = new Site();
                        site.setImei(imei);
                        site.setSite(locations);
                        site.setModel("9820E");
                        site.setProd("YUNXIN");
                        site.setTs(date);
                        int i = siteMapper.insert(site);

                        String point = siteMapper.getSite(imei);
                        poFence(imei,locations,point);

                        //应答终端
                        //String msg = "[" + head + "*" + imei + "*0006*UD_LTE]";
                        //ByteBuf respMsg = Unpooled.copiedBuffer(msg.getBytes());
                        //ctx.writeAndFlush(respMsg);
                        //ctx.flush();
                        //return;
                    }else{
                        //获取电量
                        Integer sp = Integer.valueOf(tem[13]);
                        //获取步数
                        Integer step = Integer.valueOf(tem[14]);


                        //更新设备表
                        Step step1 = new Step();
                        step1.setTs(date);
                        step1.setImei(imei);
                        step1.setStep(step.toString());
                        step1.setModel("9820E");
                        step1.setProd("YUNXIN");
                        int i = stepMapper.insert(step1);

                        Sp sp1 = spMapper.selectImei(imei);
                        Sp newSp = new Sp();
                        if(ObjectUtils.isEmpty(sp1)){
                            newSp.setTs(date);
                        }else{
                            newSp.setTs(sp1.getTs());
                        }
                        newSp.setImei(imei);
                        newSp.setModel("9820E");
                        newSp.setProd("YUNXIN");
                        newSp.setSp(sp.toString());
                        newSp.setType("1");
                        int i1 = spMapper.insertImei(newSp);

                        //获取终端状态并解析（16进制，需转成2进制，并逐位判断），暂时不解析， 报警表需要重构
                        String status = tem[16];
                        char[] chars = hexStr2Byte(status);//16进制转2进制
                        String bts ="";
                        int n = 0;
                        if("UD_LTE".equals(type) || "UD".equals(type)){
                            //获取信号最强的基站信息
                            String mcc = tem[19];
                            String s = tem[20];
                            String mnc = "";
                            if ("00".equals(s)) {
                                mnc = "0";
                            } else if ("01".equals(s)) {
                                mnc = "1";
                            }else {
                                mnc = "0";
                            }
                            String lac = tem[21];
                            String cellid = tem[22];
                            String signal = String.valueOf(Integer.parseInt(tem[23]) - 113);
                            bts = mcc + "," + mnc + "," + lac + "," + cellid + "," + signal;
                            //获取wifi列表串
                            int i3 = Integer.parseInt(tem[17]);//获取基站个数，用于计算wifi偏移量
                            n = 24 + (i3 - 1) * 3;//wifi个数位置

                        }else{
                            bts = tem[17]+","+tem[18]+","+tem[19]+","+","+","+tem[20];
                            n = 21;
                        }

                        //动态去mapkey值
                        boolean keyres = redisUtils.hasKey(NoahEnum.MAPKEYDIR.getCode()+ NoahEnum.MAPKEY.getCode());
                        if(!keyres){
                            Result result = sconfigFeign.getMapnum("0","Bearer "+GETMAKTOKEN);
                            if(!result.isFlag()){
                                redisUtils.unlook(NoahEnum.MAPLOCK.getCode());
                                return;
                            }
                            Map map = (Map) result.getData();
                            Sconfig sconfig1 = new Sconfig();
                            sconfig1.setId(Long.parseLong(map.get("id").toString()));
                            sconfig1.setMapkey(map.get("mapkey").toString());
                            sconfig1.setState( map.get("state").toString());
                            sconfig1.setType(map.get("type").toString());
                            boolean res = redisUtils.set(NoahEnum.MAPKEYDIR.getCode()+NoahEnum.MAPKEY.getCode(),sconfig1);
                            if(!res){
                                throw new RedisException();
                            }
                        }
                        Object object = redisUtils.getValue(NoahEnum.MAPKEYDIR.getCode()+ NoahEnum.MAPKEY.getCode());
                        Sconfig sconfig = (Sconfig) object;
                        Long number  = redisUtils.incr(NoahEnum.MAPKEYDIR.getCode()+NoahEnum.MAPNUMKEY.getCode(),1);
                        String mapkey = sconfig.getMapkey();
                        if(number > 2900000){
                            redisUtils.lock(NoahEnum.MAPLOCK.getCode(),10);
                            Result result1 = sconfigFeign.updateMapnum(sconfig.getId(),"Bearer "+UPDATEMAKTOKEN);
                            if(!result1.isFlag()){
                                redisUtils.unlook(NoahEnum.MAPLOCK.getCode());
                                return;
                            }
                            Result result = sconfigFeign.getMapnum("0","Bearer "+GETMAKTOKEN);
                            if(!result.isFlag()){
                                redisUtils.unlook(NoahEnum.MAPLOCK.getCode());
                                return;
                            }
                            Map map = (Map) result.getData();
                            Sconfig sconfig1 = new Sconfig();
                            sconfig1.setId(Long.parseLong(map.get("id").toString()));
                            sconfig1.setMapkey(map.get("mapkey").toString());
                            sconfig1.setState( map.get("state").toString());
                            sconfig1.setType(map.get("type").toString());
                            boolean res = redisUtils.set(NoahEnum.MAPKEYDIR.getCode()+NoahEnum.MAPKEY.getCode(),sconfig1);
                            redisUtils.del(NoahEnum.MAPKEYDIR.getCode()+NoahEnum.MAPNUMKEY.getCode());
                            redisUtils.unlook(NoahEnum.MAPLOCK.getCode());
                            mapkey = map.get("mapkey").toString();
                        }


                        String macs = "";
                        String location = "";
                        if (!"0".equals(tem[n])) {
                            for (int j = 0; j < Integer.parseInt(tem[n]); j++) {
                                macs += tem[n + (j * 3) + 2] + "," + tem[n + (j * 3) + 3] + "," + tem[n + (j * 3) + 1] + "|";
                            }
                            macs = macs.substring(0, macs.length() - 1);
                            location = otherGetMapFeign.getLocationfourg(mapkey, "0", "0", "GSM", bts, macs, imei);
                        }else{
                            location = otherGetMapFeign.getLocation(mapkey, "0", "0", "GSM", bts, imei);
                        }

                        //解析返回数据
                        JSONObject result = JSON.parseObject(location);
                        String infocode = result.getString("infocode");
                        String rtype = result.getJSONObject("result").getString("type");
                        if ("10000".equals(infocode) && !"0".equals(rtype)) {
                            String loca = result.getJSONObject("result").getString("location");
                            if(StringUtils.isEmpty(loca)){
                                return;
                            }
                            Site site = new Site();
                            site.setImei(imei);
                            site.setSite(loca);
                            site.setModel("9820E");
                            site.setProd("YUNXIN");
                            site.setTs(date);
                            int i2 = siteMapper.insert(site);
                            String point = siteMapper.getSite(imei);
                            poFence(imei,loca,point);
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    //应答终端
                    String msg = "[" + head + "*" + imei + "*0006*UD_LTE]";
                    ByteBuf respMsg = Unpooled.copiedBuffer(msg.getBytes());
                    ctx.writeAndFlush(respMsg);
                    ctx.flush();
                }
            } else if ("INFO".equals(type)) {//平台发送初始化设备参数指令，收到终端回复处理，登记设备参数表  INFO,PEDO,1,LowBat,1,FQCY,600,Wear,1,Fall,1,Shake,0
                //获取存入redis的key

            } else if ("wdstart".equals(type)) {//平台发送设置体温推送频率指令，收到终端回复处理

            } else if ("temp".equals(type)) {//解析体温数据
                try {
                    //获取体温值
                    String[] strings = message.split(",");
                    float temperature = Float.parseFloat(strings[1]);

                    /**
                     * 判断Redis中有无阈值数据---有则比较，无则查询----------------------------------------------------
                     * 判断体温是否超过阈值---是则更新，否则不作操作
                     * 此处更新表为 sysinfo 表
                     */
                    if (temperature != 0) {
                        Temp temp1 = new Temp();
                        temp1.setImei(imei);
                        temp1.setModel("9820E");
                        temp1.setProd("YUNXIN");
                        temp1.setTemp(String.valueOf(temperature));
                        temp1.setTs(date);
                        int i = tempMapper.insert(temp1);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    //应答终端
                    String msg = "[" + head + "*" + imei + "*0004*temp]";
                    ByteBuf respMsg = Unpooled.copiedBuffer(msg.getBytes());
                    ctx.writeAndFlush(respMsg);
                    ctx.flush();
                }
            } else if ("hrtstart".equals(type)) {//平台发送设置体温推送频率指令，收到终端回复处理

            } else if ("heart".equals(type)) {//解析心率数据
                try {

                    //获取心率值
                    String[] strings = message.split(",");
                    int heart = Integer.parseInt(strings[1]);

                    /**
                     * 判断Redis中有无阈值数据---有则比较，无则查询----------------------------------------------------
                     * 判断心率是否超过阈值---是则更新，否则不作操作
                     * 此处更新表为 sysinfo 表
                     */
                    if (heart != 0) {
                        Heart heart1 = new Heart();
                        heart1.setHeart(String.valueOf(heart));
                        heart1.setImei(imei);
                        heart1.setModel("9820E");
                        heart1.setProd("YUNXIN");
                        heart1.setTs(date);
                        int i = heartMapper.insert(heart1);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    //应答终端
                    String msg = "[" + head + "*" + imei + "*0005*heart]";
                    ByteBuf respMsg = Unpooled.copiedBuffer(msg.getBytes());
                    ctx.writeAndFlush(respMsg);
                    ctx.flush();
                }
            } else if ("UPLOAD".equals(type)) {//平台发送设置位置推送频率指令，收到终端回复处理

            } else if ("FIND".equals(type)) {//平台发送寻找设备指令，收到终端回复不做处理

            } else if ("rcapture".equals(type)) {//平台发送远程拍照指令，收到终端回复不做处理

            } else if ("img".equals(type)) {//图片数据暂不处理，只给终端应答
                String msg = "[" + head + "*" + imei + "*0003*img]";
                ByteBuf respMsg = Unpooled.copiedBuffer(msg.getBytes());
                ctx.writeAndFlush(respMsg);
                ctx.flush();
            } else if ("bldstart".equals(type)) {//平台发送修改终端血压上传频率，终端回复处理

            } else if ("blood".equals(type)) {//解析终端上传的血压数据
                try {
                    //获取血压值
                    String[] strings = message.split(",");
                    int hypertension = Integer.parseInt(strings[1]);
                    int hypotension = Integer.parseInt(strings[2]);
                    if ((hypertension != 0) && (hypotension != 0)) {
                        Blood blood = new Blood();
                        blood.setBlood(String.valueOf(hypertension)+","+String.valueOf(hypotension));
                        blood.setImei(imei);
                        blood.setTs(date);
                        blood.setModel("9820E");
                        blood.setProd("YUNXIN");
                        int i = bloodMapper.insert(blood);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    //应答终端
                    String msg = "[" + head + "*" + imei + "*0005*blood]";
                    ByteBuf respMsg = Unpooled.copiedBuffer(msg.getBytes());
                    ctx.writeAndFlush(respMsg);
                    ctx.flush();
                }
            } else if ("CALL".equals(type)) {////平台发送拨打电话指令，收到终端回复不做处理

            } else if ("FACTORY".equals(type)) {//平台发送恢复出厂设置指令，收到终端回复不做任何处理

            } else if ("POWEROFF".equals(type)) {//平台发送关机指令，收到终端回复后不做任何处理

            } else if ("CENTER".equals(type)) {//平台发送设置中心号码指令，收到终端回复后处理

            } else if ("SOS".equals(type)) {//平台发送设置SOS号码指令，收到终端回复后处理

            } else if ("SOSSMS".equals(type)) {//平台发送设置SOS发送短信指令指令，收到终端回复后处理

            } else if ("LOWBAT".equals(type)) {//平台发送设置低电量报警短信开关指令，收到终端回复后处理

            } else if ("REMOVE".equals(type)) {//平台发送设置SOS发送短信指令指令，收到终端回复后处理

            } else if ("MONITOR".equals(type)) {//平台发送监听指令，收到终端回复后不做处理

            } else if ("REMOVESMS".equals(type)) {//平台发送设置取下手环报警短信指令，收到终端回复后处理

            } else if ("PEDO".equals(type)) {//平台发送设置计步开关指令，收到终端回复后处理

            } else if ("WT".equals(type)) {//解析天气协议
                try {

                    //解析位置数据
                    //切割数据包
                    String[] tem = message.split(",");
                    //判断是否获取到定位数据，如果已经获取到定位数据，则需要调用高德api做坐标转换和逆地理编码解析；否则需要调用智能硬件定位接口定位
                    String flag = tem[3];
                    if("A".equals(flag)){

                        //动态去mapkey值
                        boolean keyres = redisUtils.hasKey(NoahEnum.GPSKEYDIR.getCode()+NoahEnum.GPSKEY.getCode());
                        if(!keyres){
                            Result result = sconfigFeign.getMapnum("1","Bearer "+GETMAKTOKEN);
                            if(!result.isFlag()){
                                return;
                            }
                            Map map = (Map) result.getData();
                            Sconfig sconfig1 = new Sconfig();
                            sconfig1.setId(Long.parseLong(map.get("id").toString()));
                            sconfig1.setMapkey(map.get("mapkey").toString());
                            sconfig1.setState( map.get("state").toString());
                            sconfig1.setType(map.get("type").toString());
                            boolean res = redisUtils.set(NoahEnum.GPSKEYDIR.getCode()+NoahEnum.GPSKEY.getCode(),sconfig1);
                            if(!res){
                                throw new RedisException();
                            }
                        }
                        Object object = redisUtils.getValue(NoahEnum.GPSKEYDIR.getCode()+NoahEnum.GPSKEY.getCode());
                        Sconfig sconfig = (Sconfig) object;
                        Long number  = redisUtils.incr(NoahEnum.GPSKEYDIR.getCode()+NoahEnum.GPSNUMKEY.getCode(),1);
                        String mapkey = sconfig.getMapkey();
                        if(number > 2900000){
                            redisUtils.lock(NoahEnum.GPSLOCK.getCode(),10);
                            Result result1 = sconfigFeign.updateMapnum(sconfig.getId(),"Bearer "+UPDATEMAKTOKEN);
                            if(!result1.isFlag()){
                                redisUtils.unlook(NoahEnum.GPSLOCK.getCode());
                                return;
                            }
                            Result result = sconfigFeign.getMapnum("0","Bearer "+GETMAKTOKEN);
                            if(!result.isFlag()){
                                redisUtils.unlook(NoahEnum.GPSLOCK.getCode());
                                return;
                            }
                            Map map = (Map) result.getData();
                            Sconfig sconfig1 = new Sconfig();
                            sconfig1.setId(Long.parseLong(map.get("id").toString()));
                            sconfig1.setMapkey(map.get("mapkey").toString());
                            sconfig1.setState( map.get("state").toString());
                            sconfig1.setType(map.get("type").toString());
                            boolean res = redisUtils.set(NoahEnum.GPSKEYDIR.getCode()+NoahEnum.GPSKEY.getCode(),sconfig1);
                            redisUtils.del(NoahEnum.GPSKEYDIR.getCode()+NoahEnum.GPSNUMKEY.getCode());
                            redisUtils.unlook(NoahEnum.GPSLOCK.getCode());
                            mapkey = map.get("mapkey").toString();
                        }
                        //获取经纬度
                        String longitude = tem[6];
                        String latitude = tem[4];
                        String s = longitude+","+latitude;

                        //GPS坐标转高德系坐标
                        String gps = otherMapFeign.getGDLocation(mapkey, s, "gps");
                        String locations = JSONObject.parseObject(gps).getString("locations");
                        //获取详情
                        String base = otherMapFeign.getLocationInfo(mapkey, locations, "base");
                        JSONObject regeocode = JSONObject.parseObject(base).getJSONObject("regeocode");
                        String devdesc = regeocode.getString("formatted_address");//位置详情
                        JSONObject addressComponent = regeocode.getJSONObject("addressComponent");
                        String city = addressComponent.getString("city");//城市
                        String province = addressComponent.getString("province");//省
                        String adcode = addressComponent.getString("adcode");//区域代码
                        String street = addressComponent.getJSONObject("streetNumber").getString("street");//街道
                        String country = addressComponent.getString("country");//国家
                        String citycode = addressComponent.getString("citycode");//城市代码
                        if(StringUtils.isEmpty(locations)){
                            return;
                        }

                        Site site = new Site();
                        site.setImei(imei);
                        site.setSite(locations);
                        site.setModel("9820E");
                        site.setProd("YUNXIN");
                        site.setTs(date);
                        int i = siteMapper.insert(site);

                        String point = siteMapper.getSite(imei);
                        poFence(imei,locations,point);
                    }else {
                        //获取终端剩余电量
                        Integer sp = Integer.valueOf(tem[13]);
                        //获取终端步数
                        Integer step = Integer.valueOf(tem[14]);

                        //更新设备表
                        Step step1 = new Step();
                        step1.setTs(date);
                        step1.setImei(imei);
                        step1.setStep(step.toString());
                        step1.setModel("9820E");
                        step1.setProd("YUNXIN");
                        int i = stepMapper.insert(step1);

                        Sp sp1 = spMapper.selectImei(imei);
                        Sp newSp = new Sp();
                        if(ObjectUtils.isEmpty(sp1)){
                            newSp.setTs(date);
                        }else{
                            newSp.setTs(sp1.getTs());
                        }
                        newSp.setImei(imei);
                        newSp.setModel("9820E");
                        newSp.setProd("YUNXIN");
                        newSp.setSp(sp.toString());
                        newSp.setType("1");
                        int i1 = spMapper.insertImei(newSp);

                        //获取终端状态并解析（16进制，需转成2进制，并逐位判断），暂时不解析， 报警表需要重构
                        String status = tem[16];
                        char[] chars = hexStr2Byte(status);//16进制转2进制
                        //获取信号最强的基站信息
                        String mcc = tem[19];
                        String s = tem[20];
                        String mnc = "";
                        if ("00".equals(s)) {
                            mnc = "0";
                        } else if ("01".equals(s)) {
                            mnc = "1";
                        }
                        String lac = tem[21];
                        String cellid = tem[22];
                        String signal = String.valueOf(Integer.parseInt(tem[23]) - 113);
                        String bts = mcc + "," + mnc + "," + lac + "," + cellid + "," + signal;
                        //获取wifi列表串
                        int i3 = Integer.parseInt(tem[17]);//获取基站个数，用于计算wifi偏移量
                        int n = 24 + (i3 - 1) * 3;//wifi个数位置

                        //动态去mapkey值
                        boolean keyres = redisUtils.hasKey(NoahEnum.MAPKEYDIR.getCode()+ NoahEnum.MAPKEY.getCode());
                        if(!keyres){
                            Result result = sconfigFeign.getMapnum("0","Bearer "+GETMAKTOKEN);
                            if(!result.isFlag()){
                                redisUtils.unlook(NoahEnum.MAPLOCK.getCode());
                                return;
                            }
                            Map map = (Map) result.getData();
                            Sconfig sconfig1 = new Sconfig();
                            sconfig1.setId(Long.parseLong(map.get("id").toString()));
                            sconfig1.setMapkey(map.get("mapkey").toString());
                            sconfig1.setState( map.get("state").toString());
                            sconfig1.setType(map.get("type").toString());
                            boolean res = redisUtils.set(NoahEnum.MAPKEYDIR.getCode()+NoahEnum.MAPKEY.getCode(),sconfig1);
                            if(!res){
                                throw new RedisException();
                            }
                        }
                        Object object = redisUtils.getValue(NoahEnum.MAPKEYDIR.getCode()+ NoahEnum.MAPKEY.getCode());
                        Sconfig sconfig = (Sconfig) object;
                        Long number  = redisUtils.incr(NoahEnum.MAPKEYDIR.getCode()+NoahEnum.MAPNUMKEY.getCode(),1);
                        String mapkey = sconfig.getMapkey();
                        if(number > 2900000){
                            redisUtils.lock(NoahEnum.MAPLOCK.getCode(),10);
                            Result result1 = sconfigFeign.updateMapnum(sconfig.getId(),"Bearer "+UPDATEMAKTOKEN);
                            if(!result1.isFlag()){
                                redisUtils.unlook(NoahEnum.MAPLOCK.getCode());
                                return;
                            }
                            Result result = sconfigFeign.getMapnum("0","Bearer "+GETMAKTOKEN);
                            if(!result.isFlag()){
                                redisUtils.unlook(NoahEnum.MAPLOCK.getCode());
                                return;
                            }
                            Map map = (Map) result.getData();
                            Sconfig sconfig1 = new Sconfig();
                            sconfig1.setId(Long.parseLong(map.get("id").toString()));
                            sconfig1.setMapkey(map.get("mapkey").toString());
                            sconfig1.setState( map.get("state").toString());
                            sconfig1.setType(map.get("type").toString());
                            boolean res = redisUtils.set(NoahEnum.MAPKEYDIR.getCode()+NoahEnum.MAPKEY.getCode(),sconfig1);
                            redisUtils.del(NoahEnum.MAPKEYDIR.getCode()+NoahEnum.MAPNUMKEY.getCode());
                            redisUtils.unlook(NoahEnum.MAPLOCK.getCode());
                            mapkey = map.get("mapkey").toString();
                        }

                        String macs = "";
                        String location = "";
                        if (!"0".equals(tem[n])) {
                            for (int j = 0; j < Integer.parseInt(tem[n]); j++) {
                                macs += tem[n + (j * 3) + 2] + "," + tem[n + (j * 3) + 3] + "," + tem[n + (j * 3) + 1] + "|";
                            }
                            macs = macs.substring(0, macs.length() - 1);
                            location = otherGetMapFeign.getLocationfourg(mapkey, "0", "0", "GSM", bts, macs, imei);
                        }else{
                            location = otherGetMapFeign.getLocation(mapkey, "0", "0", "GSM", bts, imei);
                        }
                        //解析返回数据
                        JSONObject result = JSON.parseObject(location);
                        String infocode = result.getString("infocode");
                        String rtype = result.getJSONObject("result").getString("type");
                        if ("10000".equals(infocode) && !"0".equals(rtype)) {
                            String loca = result.getJSONObject("result").getString("location");
                            if(StringUtils.isEmpty(loca)){
                                return;
                            }
                            Site site = new Site();
                            site.setImei(imei);
                            site.setSite(loca);
                            site.setModel("9820E");
                            site.setProd("YUNXIN");
                            site.setTs(date);
                            int i2 = siteMapper.insert(site);
                            String point = siteMapper.getSite(imei);
                            poFence(imei,loca,point);
                        }
                    }
                } catch (Exception e) {
                    //拼接返回数据
                    String msg = "[DW*" + imei + "*0002*WT]";
                    ByteBuf respMsg = Unpooled.copiedBuffer(msg.getBytes());
                    ctx.writeAndFlush(respMsg);
                    ctx.flush();
                    e.printStackTrace();
                }
            } else if ("SILENCETIME2".equals(type)) {//平台发送设置上课禁用指令，收到终端回复后处理

            } else if ("REMIND".equals(type)) {//平台发送设置闹钟指令，收到终端回复后处理

            } else if ("PHL".equals(type)) {//平台发送设置电话号码指令，收到终端回复后处理

            } else if ("WLKEY".equals(type)) {//平台发送设置低电量报警短信开关指令，收到终端回复后处理

            } else if ("FALLDOWN".equals(type)) {//平台发送设置低电量报警短信开关指令，收到终端回复后处理

            } else if ("SHAKE".equals(type)) {//平台发送设置低电量报警短信开关指令，收到终端回复后处理

            } else if ("KEYBRD".equals(type)) {//平台发送设置低电量报警短信开关指令，收到终端回复后处理

            }
            return;
        }

    //汉字转unicode
    public String toUnicode(String str) {
        String outStr = "";
        for (int i = 0; i < str.length(); i++) {
            int ch = (int) str.charAt(i);
            outStr += Integer.toHexString(ch);
        }
        return outStr;
    }

    //16进制转2进制
    public char[] hexStr2Byte(String hex) {
        int i = Integer.parseInt(hex, 16);
        return Integer.toBinaryString(i).toCharArray();
    }

    //10进制转16进制(固定4位长度)
    public String demical2Hex(int i) {
        StringBuffer len = new StringBuffer();
        String s = Integer.toHexString(i);
        int length = s.length();
        if (length < 4) {
            for (int j = 0; j < (4 - length); j++) {
                len.append("0");
            }
            len.append(s);
        }
        return len.toString();

    }

    /**
     * 判断围栏进出报警接口
     * @param imei
     * @param loca
     * @param site
     */
    public void poFence(String imei, String loca, String site) {
        boolean keyres = redisUtils.hasKey(NoahEnum.FENCEDIR.getCode()+imei);
        if(!keyres){
            return;
        }
        List<Object> list1 = redisUtils.lGet(NoahEnum.FENCEDIR.getCode()+imei,0,-1);
        if(ObjectUtils.isEmpty(list1)){
            return;
        }
        for (Object object : list1) {
            Fence fence = (Fence) object;
            if(fence.getStatus().equals("1")){
                continue;
            }

            String[] pointC = fence.getPoint().split(",");
            Double pointCx = Double.parseDouble(pointC[0]);//围栏圆心的经度
            Double pointCy = Double.parseDouble(pointC[1]);//围栏圆心的纬度

            String[] pointloca = loca.split(",");
            Double pointlocax = Double.parseDouble(pointloca[0]); //现在x坐标
            Double pointlocay = Double.parseDouble(pointloca[1]); //现在y坐标

            String[] pointsite = site.split(",");
            Double pointsitex = Double.parseDouble(pointsite[0]); // 上次x坐标
            Double pointsitey = Double.parseDouble(pointsite[1]);//上次y坐标

            double lon1 = (Math.PI / 180) * pointlocax;//最近时间经度
            double lat1 = (Math.PI / 180) * pointlocay;//最近时间纬度

            double lon2 = (Math.PI / 180) * pointsitex;//前一次时间纬度
            double lat2 = (Math.PI / 180) * pointsitey;//前一次时间纬度
            double lonC = (Math.PI / 180) * pointCx;//圆心经度
            double latC = (Math.PI / 180) * pointCy;//圆心纬度

            // 地球半径
            double R = 6378124;

            // 两点间距离 km，如果想要米的话，结果*1000就可以了
            double dstart = Math.acos(Math.sin(lat1) * Math.sin(latC) + Math.cos(lat1) * Math.cos(latC) * Math.cos(lonC - lon1)) * R;//最近时间经纬度到圆心的距离
            double dend = Math.acos(Math.sin(lat2) * Math.sin(latC) + Math.cos(lat2) * Math.cos(latC) * Math.cos(lonC - lon2)) * R;//前一次时间经纬度到圆心的距离
            Map<String,String> map = null;
            Alarm alarm = new Alarm();

            if (fence.getAlarm().equals("0") && (dstart <= fence.getRadius() && dend > fence.getRadius())) {
                //进围栏报警
                //App报警信息-----------
                String msg1 = "进入" + fence.getName() + "围栏报警！";
                String type = "in";
                //异步调用报警feign
                alarm.setImei(imei);
                alarm.setAlarm(msg1);
                alarm.setType(type);
                alarmFeign.addAlarm(alarm,"Bearer "+TOKEN);
            } else if (fence.getAlarm().equals("1") && (dend <= fence.getRadius() && dstart > fence.getRadius())) {
                //出围栏报警
                //App报警信息-----------
                String msg1 = "离开" + fence.getName() + "围栏报警！";
                String type = "out";
                alarm.setImei(imei);
                alarm.setAlarm(msg1);
                alarm.setType(type);
                alarmFeign.addAlarm(alarm,"Bearer "+TOKEN);

            } else if (fence.getAlarm().equals("2")) {
                //进出围栏报警
                if (dstart <= fence.getRadius() && dend > fence.getRadius()) {
                    //进围栏报警
                    //App报警信息-----------
                    String msg1 = "进入" + fence.getName() + "围栏报警！";
                    String type = "in";
                    alarm.setImei(imei);
                    alarm.setAlarm(msg1);
                    alarm.setType(type);
                    alarmFeign.addAlarm(alarm,"Bearer "+TOKEN);

                } else if (dend <= fence.getRadius() && dstart > fence.getRadius()) {
                    //出围栏报警
                    //App报警信息-----------
                    String msg1 = "离开" + fence.getName() + "围栏报警！";
                    String type = "out";
                    alarm.setImei(imei);
                    alarm.setAlarm(msg1);
                    alarm.setType(type);
                    alarmFeign.addAlarm(alarm,"Bearer "+TOKEN);
                    //登记系统信息表
                }
            }
        }
        return;
    }

}
